package com.ease.dao.vo;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.ease.common.vo.Ordering;
import com.ease.common.vo.Pagination;
import com.ease.dao.DataAccessObjectConst;

/**
 * 
 * @author nathanleewei
 * 
 */
public class PaginationMapParameter implements Map<String, Object>, DataAccessObjectConst {

	private Map<String, Object> delegateParameters;

	public Map<String, Object> getDelegateParameters() {
		return delegateParameters;
	}

	public void setDelegateParameters(Map<String, Object> delegateParameters) {
		this.delegateParameters = delegateParameters;
	}

	public PaginationMapParameter() {
		init(null, null);
	}

	// eg:entityTypeId=1;locationId>0
	// now just for simple operation
	private String appendCriteria;

	public String getAppendCriteria() {
		return appendCriteria;
	}

	public void setAppendCriteria(String appendCriteria) {
		this.appendCriteria = appendCriteria;
	}

	private Ordering ordering;

	private Pagination<?> pagination;

	private int pageCount = -1;

	/**
	 * 指定起始页和分页数量查询<br>
	 * 如：共5页,查询第2页开始的2页(即查询第2页和第3页)
	 * 
	 * @param parameters
	 * @param ordering
	 * @param pageSize
	 *            每页的记录数
	 * @param pageIndex
	 *            起始页码
	 * @param pageCount
	 *            查询的分页数量
	 */
	public PaginationMapParameter(Map<String, Object> parameters, Ordering ordering, Pagination<?> pagination, int pageCount) {
		this(parameters, ordering, pagination);
		if (pagination != null && pagination.getIndex() <= 0) {
			throw new IllegalArgumentException("pageIndex must > 0");
		}
		if (pagination != null && pageCount > 1) {
			this.pageCount = pageCount;
			delegateParameters.put(SKIP_RESULTS, pagination.getSize() * (pagination.getIndex() - 1));
			delegateParameters.put(MAX_RESULTS, pagination.getSize() * (pagination.getIndex() + pageCount - 1));
		}
	}

	public void setPageCount(int pageCount) {
		this.pageCount = pageCount;
	}

	public PaginationMapParameter(Map<String, Object> parameters, Ordering ordering, int skipResult, int maxResult) {
		init(parameters, ordering);
		delegateParameters.put(SKIP_RESULTS, skipResult);
		delegateParameters.put(MAX_RESULTS, maxResult);
	}

	public PaginationMapParameter(Map<String, Object> parameters, Ordering ordering, Pagination<?> pagination) {
		init(parameters, ordering);
		this.pagination = pagination;
		if (null != pagination) {
			delegateParameters.put(SKIP_RESULTS, new Integer(pagination.getStart()));
			delegateParameters.put(MAX_RESULTS, new Integer(pagination.getStart() + pagination.getSize()));
		}
	}

	private void init(Map<String, Object> parameters, Ordering ordering) {
		this.ordering = ordering;
		if (null == parameters) {
			delegateParameters = new HashMap<String, Object>();
		} else {
			delegateParameters = parameters;
		}

		if (null != ordering) {
			delegateParameters.put(ORDER_BY, ordering.orderClause());
		}
	}

	/**
	 * 
	 * @see java.util.Map#clear()
	 */
	public void clear() {
		delegateParameters.clear();
	}

	/**
	 * @param key
	 * @return
	 * @see java.util.Map#containsKey(java.lang.Object)
	 */
	public boolean containsKey(Object key) {
		return delegateParameters.containsKey(key);
	}

	/**
	 * @param value
	 * @return
	 * @see java.util.Map#containsValue(java.lang.Object)
	 */
	public boolean containsValue(Object value) {
		return delegateParameters.containsValue(value);
	}

	/**
	 * @return
	 * @see java.util.Map#entrySet()
	 */
	public Set<java.util.Map.Entry<String, Object>> entrySet() {
		return delegateParameters.entrySet();
	}

	/**
	 * @param o
	 * @return
	 * @see java.util.Map#equals(java.lang.Object)
	 */
	public boolean equals(Object o) {
		return delegateParameters.equals(o);
	}

	/**
	 * @param key
	 * @return
	 * @see java.util.Map#get(java.lang.Object)
	 */
	public Object get(Object key) {
		return delegateParameters.get(key);
	}

	/**
	 * @return
	 * @see java.util.Map#hashCode()
	 */
	public int hashCode() {
		return delegateParameters.hashCode();
	}

	/**
	 * @return
	 * @see java.util.Map#isEmpty()
	 */
	public boolean isEmpty() {
		return delegateParameters.isEmpty();
	}

	/**
	 * @return
	 * @see java.util.Map#keySet()
	 */
	public Set<String> keySet() {
		return delegateParameters.keySet();
	}

	/**
	 * @param key
	 * @param value
	 * @return
	 * @see java.util.Map#put(java.lang.Object, java.lang.Object)
	 */
	public Object put(String key, Object value) {
		return delegateParameters.put(key, value);
	}

	/**
	 * @param m
	 * @see java.util.Map#putAll(java.util.Map)
	 */
	public void putAll(Map<? extends String, ? extends Object> m) {
		delegateParameters.putAll(m);
	}

	/**
	 * @param key
	 * @return
	 * @see java.util.Map#remove(java.lang.Object)
	 */
	public Object remove(Object key) {
		return delegateParameters.remove(key);
	}

	/**
	 * @return
	 * @see java.util.Map#size()
	 */
	public int size() {
		return delegateParameters.size();
	}

	/**
	 * @return
	 * @see java.util.Map#values()
	 */
	public Collection<Object> values() {
		return delegateParameters.values();
	}

	public Ordering getOrdering() {
		return ordering;
	}

	public void setOrdering(Ordering ordering) {
		this.ordering = ordering;
	}

	@SuppressWarnings("unchecked")
	public Pagination getPagination() {
		return pagination;
	}

	public void setPagination(Pagination<?> pagination) {
		this.pagination = pagination;
	}

	public boolean isPaginationed() {
		return pagination != null;
	}

	public int getPageCount() {
		return pageCount;
	}

	public int getSkipResult() {
		Object o = delegateParameters.get(SKIP_RESULTS);
		return o != null ? (Integer) o : 0;
	}

	public int getMaxResult() {
		Object o = delegateParameters.get(MAX_RESULTS);
		return o != null ? (Integer) o : 0;
	}

	public String toString() {
		return delegateParameters.toString();
	}
}
